package cn.autumnorange.app.util.consumer.queue;

import cn.autumnorange.app.common.provider.queue.Order;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.Message;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class RabbitReceiver {


    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue-1",
                    durable="true"),
            exchange = @Exchange(value = "exchange-1",
                    durable="true",
                    type= "topic",
                    ignoreDeclarationExceptions = "true"),
            key = "springboot.*"
    )
    )
    @RabbitHandler
    public void onMessage(Message message, Channel channel) throws Exception {
        log.info("消费端Payload: " + message.getPayload());
        Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
   try{
       if(System.currentTimeMillis()%2==0){
           throw new RuntimeException("随机异常校验是否队列服务重新发送数据");
       }
       // 手工ACK  // 处理成功则签收：1、签收的 deliveryTag；2、是否批量签收
       log.info("手工ACK basicAck: " +deliveryTag);

       channel.basicAck(deliveryTag, false);
    } catch (Exception e) {
       log.info("手工ACK 失败,执行basicNack(deliveryTag, false, true);是否把消息返回给服务器 " +deliveryTag);

       // 处理失败退签：1、退签的 deliveryTag；2、是否批量操作；3、是否把消息返回给服务器
        channel.basicNack(deliveryTag, false, true);
    }


    }


    /**
     *
     *     spring.rabbitmq.listener.order.queue.name=queue-2
     spring.rabbitmq.listener.order.queue.durable=true
     spring.rabbitmq.listener.order.exchange.name=exchange-1
     spring.rabbitmq.listener.order.exchange.durable=true
     spring.rabbitmq.listener.order.exchange.type=topic
     spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions=true
     spring.rabbitmq.listener.order.key=springboot.*
     * @param order
     * @param channel
     * @param headers
     * @throws Exception
     */
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${spring.rabbitmq.listener.order.queue.name}",
                    durable="${spring.rabbitmq.listener.order.queue.durable}"),
            exchange = @Exchange(value = "${spring.rabbitmq.listener.order.exchange.name}",
                    durable="${spring.rabbitmq.listener.order.exchange.durable}",
                    type= "${spring.rabbitmq.listener.order.exchange.type}",
                    ignoreDeclarationExceptions = "${spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions}"),
            key = "${spring.rabbitmq.listener.order.key}"
    )
    )
    @RabbitHandler
    public void onOrderMessage(@Payload Order order,
                               Channel channel,
                               @Headers Map<String, Object> headers) throws Exception {
        System.err.println("--------------------------------------");
        System.err.println("消费端order: " + order.getId());
        Long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);

        try{
            if(System.currentTimeMillis()%2==0){
                throw new RuntimeException("随机异常校验是否队列服务重新发送数据");
            }
            // 手工ACK  // 处理成功则签收：1、签收的 deliveryTag；2、是否批量签收
            log.info("手工ACK basicAck: " +deliveryTag);

            channel.basicAck(deliveryTag, false);
        } catch (Exception e) {
            log.info("手工ACK 失败,执行basicNack(deliveryTag, false, true);是否把消息返回给服务器 " +deliveryTag);

            // 处理失败退签：1、退签的 deliveryTag；2、是否批量操作；3、是否把消息返回给服务器
            channel.basicNack(deliveryTag, false, true);
        }
    }


}
